<?php

/*-----------------------------------------
MAGIC - User System Framework

This class provid's the primary usersystem functions used within a webpage

@Version: 2009.05.26
@Author: Carl
@Licence: LGPL -  http://www.gnu.org/licenses/lgpl.html
@Copyright (c) thybag.co.uk 2009
-----------------------------------------*/

class UserSystem{

	//Define class varibles
	private $db;
	private $config;
	private $validator;
	private $userCache = Array();
	private $currentUser = null;


	/*
	Construct
	Creates a new user system Object based on details specifed in magic_config.php
	*/
	public function __construct() {
		global $config;
		
		//Initialize Variables
		$this->config = $config;
		$this->validator = new Validator();
		$this->db = new Database();
		
		//Set current user
		if(isset($_SESSION[md5($this->config['site_url'])])){
			//logged in id.

			$uid = $_SESSION[md5($this->config['site_url'])];
			$this->currentUser = $this->loadUser($uid);// Set as User
		}else{
			$this->currentUser = $this->loadUser(0);// set as Guest
		}
		
	}
	
	/*
	Login
	Provided with a username and password this class will create a new user Session if they match an account
	and successfully login.
	
	@param: $username - name of user trying to log in
	@param: $password - password of user trying to log in
	@return: true on successful login
	*/
	public function login($username,$password){
			
		//get user
		$user = $this->getUserByName(trim($username));
		
		//password hash takes in to account userid's
		$password = User::passwordHash($password,$this->config['salt']);
		//echo $password."\n".$user->getPassword();
		if($password == $user->getPassword()){
			//Login
			$this->setCurrentUser($user);
			return true;
		}else{
			//return false;
			die("loggin attempt failed");
		}
	}
	
	
	/*
	Logout
	Destroys current user session to successfully log a user out
	*/
	public function logout(){
		session_destroy();
		//logged out
 	}
	
	/*
	authenticaded
	Works out whether or not user is successfully logged in
	@return true or false on whether user is logged in or not (true= loggedin)
	*/
	public function authenticated(){
		return ($this->getAttribute('uid')!=='0');
	}
	
	/*
	 getCurrentUser
	Retrurns the Current user's User object to calling function
	*/
	public function getCurrentUser(){
			return $this->currentUser;
	}
	/*
	 getUserById
	Retrurns the user object for userid specifed
	*/
	public function getUserById($uid){
		return $this->loadUser($uid);
	}
	/*
	 getUserByName
	Retrurns the user object for user with specified name
	*/
	public function getUserByName($username){
		return $this->loadUser($username,'name');
	}

	/*
	getAttribute
	Provides direct access to current user attributes. 
	*/
	public function getAttribute($attribute){
			return $this->currentUser->get($attribute);
	}
		
	/*
	getUserList
	Returns array $user->$id specifing current users
	*/
	public function getUserList($limit = 50,$from=0){	
		return $this->db->get_rows('users',array('uid','name'),$from,$limit);//limit 0 = return all	
	}
	
	/*
	updateCurrentUser
	Takes assosative array of userDetails and pushes them to current users userObject
	Changes saved to database
	*/	
	public function updateCurrentUser($array){
	
		//Are they logged in?
		if(!$this->authenticated()) return false; // if is guest, theres no one to edit
		
		//get current user
		$you = $this->getCurrentUser();
		$this->updateUserAccount($array,$you);

	}
	/*
	updateUser
	Takes assosative array of userDetails and pushes them to specified users userObject
	Changes saved to database
	*/	
	public function updateUser($array,$uid){
	
		$usr = $this->getUserById($uid);//get user
		//push changes to object
		$this->updateUserAccount($array,$usr);
	}
	
	/*
	makeNewUser
	Must be provided with specific paramaters needed to create a new user in the system
	
	Validaton fails
	0 - password mismatch
	1 - email incorrect
	2 - Username is taken
	*/
	public function makeNewUser($user,$pass,$pass2,$additional_data_keyed=array()){
	
		//Use the guest user model as are shell
		if($pass !== $pass2) return 0;//passwords dont match
	
		$n = new User;
		$n->set('name',$user);
		$n->setPassword($pass);
		$n->set('registered',time());
		$n->setPermissions('2');
		//attempt to set additional data
		foreach($additional_data_keyed as $key=>$val){
			$n->set($key,$val);
		}

		$n->write();
	}
	
	
	/*-----------------------------------------
	Private Methods
	
	Methods below this point are private and can only be used internally
	-----------------------------------------*/

	/*
	setCurrentUser
	Update session and currentuser value to new userobject
	*/
	private function setCurrentUser($user){
		$_SESSION[md5($this->config['site_url'])] = $user->getUid();
		$this->currentUser = $user;
	}

	/*
	getUserInfo
	Returns a user object based on paramiters. Takes care of user Cacheing
	*/
	private function loadUser($uid, $findby = 'id'){
		if(isset($this->userCache[$uid])){
			$user = $this->userCache[$uid]; //cache
		}else{
			//If searching by name
			if($findby !=='id'){
				$usr = $this->db->get_row('users', 'name', $uid);
				$uid = $usr['uid'];
			}
			//create and return user
			$user = new User($uid);
			$this->userCache[$uid] = $user;
		}
		//print_r($user);
		return $user;
	}
	/*
	updateUserAccount
	Performs updates on user account and pushes result to database
	*/
	private function updateUserAccount($valueArray,$userObject){
	
		if($userObject==null) return false;
		
		//Go through each attribute assigning them to the user.
		foreach($valueArray as $key=>$val){
			$userObject->set($key,$val);
		}
		$userObject->write();
	}

	
	
}
